package com.cn.delan.web.mvc.admin.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;

import com.cn.delan.core.util.DateUtil;
import com.cn.delan.core.util.FileUtil;
import com.cn.delan.web.mvc.admin.AdminConst;
import com.cn.delan.web.mvc.admin.service.IZipService;

public class ZipService extends Thread implements IZipService {
	private static Hashtable<String,ZipService> ziping = new Hashtable<String,ZipService>();
	private String path;
	//完成zip的百分比
	private long percent;
	private File file;
	private File zipFile;
	//要压缩的文件总大小
	private long totalSize;
	//压缩了的文件大小
	private long zipSize;
	//message为非空字符串时表示zip报错
	private String message = "";
	
	public ZipService(){
		
	}
	private ZipService(String path){
		this.path = path;
		this.percent = 0;
	}
	@Override
	synchronized public IZipService zip(String path) {
		ZipService service = ZipService.ziping.get(path);
		if(service==null){
			this.file = new File(path);
			File parentFile = file.getParentFile();
			this.zipFile = new File(parentFile,file.getName()+"_"+DateUtil.now("yyyyMMdd")+".jar");
			service = new ZipService(path);
			service.setFile(this.file);
			service.setZipFile(this.zipFile);
			service.setTotalSize(FileUtil.size(this.file));
			if(file.exists()){
				if(zipFile.exists()){
					//service.setMessage(zipFile.getAbsolutePath()+"{"+AdminConst.ERROR_0002+"}");
					//压缩文件已存在，代表打包操作已完成。
					service.setMessage("");
					service.setPercent(100);
				}else{
					ZipService.ziping.put(path, service);
					service.start();
				}
			}else{
				service.setMessage(file.getAbsolutePath()+"{"+AdminConst.MESSAGE_FILE_NOTEXISTS+"}");
			}
		}
		return service;
	}
	@Override
	public void run() {
		try{
			this.zip(this.file,this.zipFile);
		}catch(IOException e){
			this.message = e.getMessage();
		}finally{
			ZipService.ziping.remove(path);
		}
	}
	private void zip(File file,File zipFile) throws IOException{
		FileOutputStream fos = new FileOutputStream(zipFile);
		JarOutputStream jos = new JarOutputStream(fos);
		int plen = file.getAbsolutePath().length() - file.getName().length();
		if(file.isFile()){
			jos.putNextEntry(new ZipEntry(file.getName()));
			FileInputStream fis = new FileInputStream(file);
			byte []b = new byte[2000];
			int len = -1;
			while((len=fis.read(b))!=-1){
				jos.write(b, 0, len);
				this.zipSize+=len;
				this.percent=this.zipSize*100/this.totalSize;
			}
			jos.closeEntry();
		}else{
			jos.putNextEntry(new ZipEntry(file.getName()+"/"));
			jos.closeEntry();
			for(File subFile:file.listFiles()){
				this.zip(jos,subFile,plen);
			}
		}
		jos.finish();
		jos.close();
	}
	private void zip(JarOutputStream jos,File file,int plen) throws IOException{
		if(file.isFile()){
			jos.putNextEntry(new ZipEntry(file.getAbsolutePath().substring(plen)));
			FileInputStream fis = new FileInputStream(file);
			byte []b = new byte[2000];
			int len = -1;
			while((len=fis.read(b))!=-1){
				jos.write(b, 0, len);
				this.zipSize+=len;
				this.percent=this.zipSize*100/this.totalSize;
			}
			jos.closeEntry();
		}else{
			jos.putNextEntry(new ZipEntry(file.getAbsolutePath().substring(plen)+"/"));
			jos.closeEntry();
			for(File subFile:file.listFiles()){
				this.zip(jos,subFile,plen);
			}
		}
	}
	public long getPercent() {
		return this.percent;
	}
	public long getTotalSize() {
		return this.totalSize;
	}
	public String getMessage(){
		return this.message;
	}
	private void setTotalSize(long totalSize){
		this.totalSize = totalSize;
	}
	private void setFile(File file) {
		this.file = file;
	}
	private void setZipFile(File zipFile) {
		this.zipFile = zipFile;
	}
	private void setMessage(String message) {
		this.message = message;
	}
	private void setPercent(long percent) {
		this.percent = percent;
	}
}
